<!--
## 组件的自定义事件

1. 一种组件间通信的方式，适用于：<strong style="color:red">子组件 ===> 父组件</strong>
2. 使用场景：A是父组件，B是子组件，B想给A传数据，那么就要在A中给B绑定自定义事件（<span style="color:red">
   事件的回调在A中</span>）。
3. 绑定自定义事件：
    1. 第一种方式，在父组件中：```<Demo @atguigu="test"/>```  或 ```<Demo v-on:atguigu="test"/>```
    2. 第二种方式，在父组件中：
        ```
        <Demo ref="demo"/>
        ......
        mounted(){
           this.$refs.xxx.$on('atguigu',this.test)
        }
        ```
    3. 若想让自定义事件只能触发一次，可以使用```once```修饰符，或```$once```方法。
4. 触发自定义事件：```this.$emit('atguigu',数据)```
5. 解绑自定义事件```this.$off('atguigu')```
6. 组件上也可以绑定原生DOM事件，需要使用```native```修饰符。
7. 注意：通过```this.$refs.xxx.$on('atguigu',回调)```绑定自定义事件时，回调<span style="color:red">
   要么配置在methods中</span>，<span style="color:red">要么用箭头函数</span>，否则this指向会出问题！
-->

<template>
  <div class="app">
    <h1> {{ msg }} 学生姓名：{{ studentName }}</h1>
    <!-- 通过父组件给子组件传递函数类型的props实现：子组件给父组件传递数据 -->
    <School :getSchoolName="getSchoolName"></School>
    <!-- Student 组件使用，自定义事件的方式，将子组件给父组件传递数据 -->
    <!-- 通过父组件给子组件绑定一个自定义事件实现：子组件给父组件传递数据【第一种写法：使用@ 或者 v-on】-->
    <!-- <Student v-on:atguigu.once="getStudentName"></Student>-->
    <!-- <Student @atguigu.once="getStudentName"></Student>-->

    <!-- 自定义事件@atguigu、@demo -->
    <!-- <Student @atguigu="getStudentName" @demo="m1"></Student> -->

    <!-- ref属性用法：可以通过this.$refs.student 获取到Student 这个组件的实例对象【第二种写法：使用ref】 -->
    <Student ref="student" @click.native="show()"></Student>
    <!-- 其中原生的@click点击事件，如果想要其生效的话，需要加上.native即可，其中native表示的是原生的。 -->
  </div>
</template>

<script>
// 第一步：引入组件，其中在脚手架里面，后缀.vue写不写都可以
import Student from './components/Student.vue'
import School from "./components/School.vue";

export default {
  name: 'App',
  // 第二步：注册组件
  // components: {
  //   School,
  //   Student,
  // }
  // 使用对象写法
  components: {
    Student,
    School,
  },
  data() {
    return {
      msg: '欢迎学习Vue，我在尚硅谷学习Vue!!!',
      studentName: '',
    }
  },
  methods: {
    getSchoolName(name) {
      console.log('App收到了学校名称name：', name);
    },
    // 使用自定义事件，让子组件给父组件传递数据
    getStudentName(name, ...params) {
      console.log('demo被调用了！');
      console.log('App收到了学生名称name：', name, params);
      this.studentName = name;
    },
    // // 使用自定义事件，让子组件给父组件传递数据
    // m1() {
    //   console.log('m1被触发了！！！');
    // },
    show() {
      console.log("点我显示Show Time!!!");
      alert("点我显示Show Time!!!");
    }
  },
  // 其中Vue的生命周期 mounted挂载钩子，mounted挂载完毕代表的是这个App组件挂载完毕之后。
  // 其中mounted写到那个组件里面就代表那个组件挂载完毕。
  mounted() {
    // 当mounted钩子挂载完毕就触发
    console.log('@@@', this.$refs.student.name);
    // // 其中$on代表的是触发事件，其中参数一代表的是什么事件，参数二代表的是触发什么事件。
    // this.$refs.student.$on('atguigu', this.getStudentName); // 绑定一次性事件


    // // 其中使用 mounted()挂载的方式非常灵活
    // setTimeout(() => {
    //   // 其中$on代表的是触发事件，其中参数一代表的是什么事件，参数二代表的是触发什么事件。
    //   // this.$refs.student.$on('atguigu', this.getStudentName); // 绑定一次性事件
    //   // 其中使用$once的话，就只能触发一次
    //   this.$refs.student.$once('atguigu', this.getStudentName); // 绑定一次性事件【一次性】
    // }, 3000)

    // 如果使用箭头函数的话，this就是往外找，否则使用普通函数的话，this就是Student组件的vc
    this.$refs.student.$on('atguigu', (name, ...params) => {
      console.log('demo被调用了！');
      console.log('App收到了学生名称name：', name, params);
      this.studentName = name;
    }); // 绑定一次性事件
  }

}
</script>

<style>
.app {
  background-color: gray;
  padding: 5px;
}
</style>